/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package view;

/*
Cours :             LOG120 
Session :           Saison (hiver) 
Groupe :            01 
Projet :            Laboratoire #2
Etudiant(e)(s) :    Jeremy Moreau
                    Alexandre Richard
                    Philippe Pigeon
Code(s) perm. :     MORJ91010106
					RICA10028806 
                    PIGP08058903
Professeur :        Ghizlane El Boussaidi  
Date remise :       2012-03-010  
*/

import controller.LivraisonController;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.List;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Observable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.border.LineBorder;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*;
import model.Commande;
import model.LigneCommande;
import model.LigneCommandeRestaurant;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

/**
 *
 * @author aj91000
 */
public class GoogleMapView extends AbstractView
{
	BufferedImage img; 
	public int MAP_WIDTH = 640;
	public int MAP_HEIGHT = 640;
	//long lastRequest;
	
	public GoogleMapView(LivraisonController _ctrl)
	{
		super(_ctrl);
		
		setLayout(null);
		setBorder(new LineBorder(Color.BLACK));		
	}
	
	private void getRouteForAdress(String origin, String dest, ArrayList<String> waypoints)
	{
		String xml = getXMLfromGoogle(origin, dest, waypoints);
		String polyLinePoints = parseXMLtoPolyLinePoints(xml);
		getGoogleRouteImage(polyLinePoints, waypoints, origin, dest);
		repaint();
	}
	
	private String getXMLfromGoogle(String origin, String destination, ArrayList<String> waypoints)
	{
		String xmlResponse = "";
		String waypointString = "optimize:true";
		for(String wp : waypoints)
			waypointString += "|" + wp;
		
		try
		{
			URL googleMapsURL = new URL("http://maps.googleapis.com/maps/api/directions/xml?origin="+origin+"&destination="+destination+"&waypoints="+waypointString+"&sensor=false");
			BufferedReader reader = new BufferedReader(new InputStreamReader(googleMapsURL.openStream()));
			String line;
			while( (line = reader.readLine()) != null)
			{
				xmlResponse += line + "\n";
			}
		}
		catch(Exception e){ e.printStackTrace(); }
		return xmlResponse;
	}
	
	private String parseXMLtoPolyLinePoints(String xmlString)
	{
		try 
		{
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			dbf.setNamespaceAware(true);
			DocumentBuilder db = dbf.newDocumentBuilder();
			
			Document doc = db.parse(new InputSource(new StringReader(xmlString)));
			
			XPathExpression xpe = XPathFactory.newInstance().newXPath()
					.compile("/DirectionsResponse/route/overview_polyline/points/text()");
			NodeList nodes = (NodeList) xpe.evaluate(doc, XPathConstants.NODESET);
			
			return nodes.item(0).getNodeValue();
		} 
		catch (NullPointerException npe) { JOptionPane.showMessageDialog(this, "La location du livreur ou de la commande est invalide", "Adresse invalide", JOptionPane.ERROR_MESSAGE); }
		catch (Exception ex) 
		{
			Logger.getLogger(GoogleMapView.class.getName()).log(Level.SEVERE, null, ex);
		}
		return "";
	}
	
	private Object getGoogleRouteImage(String polylineData, ArrayList<String> waypoints, String origin, String dest)
	{
		
		String markersString = "&markers=color:green|"+origin+"&markers=color:red|"+dest+"&markers=color:blue"; 
		for(String wp : waypoints)
			markersString += "|" + wp;
		
		try
		{
			URL googleRouteURL = new URL("http://maps.googleapis.com/maps/api/staticmap?size="+MAP_WIDTH+"x"+MAP_HEIGHT+""+markersString+"&sensor=false&path=weight:3%7Ccolor:red%7Cenc:"+polylineData);
			img = ImageIO.read(googleRouteURL);
        }
		catch(Exception e) { e.printStackTrace(); } 
                
		return null;
	}
	
		@Override
	public void paintComponent(Graphics g) 
	{
		super.paintComponent(g);
		g.drawImage(img, 0, 0, MAP_WIDTH, MAP_HEIGHT, null);
	}

	@Override
	public void update(Observable o, Object o1) 
	{
		//if(lastRequest+500 > Calendar.getInstance().getTimeInMillis()) return;
		//lastRequest = Calendar.getInstance().getTimeInMillis();
		
		Commande c = ((Commande)o);
		ArrayList<String> waypoints = new ArrayList<String>();
		for(LigneCommandeRestaurant lc : c.getLignesCommandeRestaurant())
		{
			waypoints.add(lc.getRestaurant().getAdresse().replace(" ", "%20"));
		}
		getRouteForAdress(getLCtrl().getCurrentLocation(), c.getAdresse().replace(" ", "%20"), waypoints);
	}
	
}
